
package de.uni.wuppertal.server.ui.support;

import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractListModel;

import de.uni.wuppertal.server.*;

/**
 * @author Martin Schröder
 * @author Patrik Nordsiek
 */
public class LogListModel extends AbstractListModel
{
	public static final int SHOW_INFORMATION = 1;
	public static final int SHOW_WARNING = 2;
	public static final int SHOW_ERROR = 4;
	public static final int SHOW_DEBUG = 8;
	
	private static final long serialVersionUID = 1L;
	
	private int filter;
	
	private int limit = 200;
	private Vector<LogEntry> entries;
	private List<LogEntry> filteredEntries = new ArrayList<LogEntry>();
	
	public LogListModel()
	{
		filter = SHOW_INFORMATION | SHOW_WARNING | SHOW_ERROR | SHOW_DEBUG;
		
		entries = new Vector<LogEntry>();
		entries.ensureCapacity(limit);
	}
	
	public synchronized void addFilter(int flag)
	{
		filter |= flag;
		
		refreshFilteredEntries();
	}
	
	public synchronized void removeFilter(int flag)
	{
		filter = (filter | flag) ^ flag;
		
		refreshFilteredEntries();
	}
	
	public synchronized void prepend(LogEntry entry)
	{
		entries.insertElementAt(entry, 0);
		
		if(entries.size() > limit)
		{
			entries.remove(entries.lastElement());
		}
		
		refreshFilteredEntries();
	}
	
	@Override
	public Object getElementAt(int index)
	{
		try
		{
			return filteredEntries.get(index);
		}
		catch(Throwable e)
		{
			return null;
		}
	}
	
	@Override
	public int getSize()
	{
		return filteredEntries.size();
	}
	
	private synchronized void refreshFilteredEntries()
	{
		filteredEntries.clear();
		
		for(LogEntry entry : entries)
		{
			if((filter & SHOW_INFORMATION) > 0 && entry instanceof InformationLogEntry)
			{
				filteredEntries.add(entry);
			}
			
			if((filter & SHOW_WARNING) > 0 && entry instanceof WarningLogEntry)
			{
				filteredEntries.add(entry);
			}
			
			if((filter & SHOW_ERROR) > 0 && entry instanceof ErrorLogEntry)
			{
				filteredEntries.add(entry);
			}
			
			if((filter & SHOW_DEBUG) > 0 && entry instanceof DebugLogEntry)
			{
				filteredEntries.add(entry);
			}
		}
		
		EventQueue.invokeLater(new Runnable()
		{
			@Override
			public void run()
			{
				fireContentsChanged(LogListModel.this, 0, entries.size() - 1);
			}
		});
	}
}
